/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ora_rowid_accessor.c                               */
/*  NOTE      =                                                    */
/*  DATE      = 2015/01/14 by songbb                               */
/*******************************************************************/

#include "frcomm.h"
#include "frlog.h"

#include "conntrack.h"
#include "frct_comm.h"

#include "../../ora_core.h"
#include "../../comm/ora_comm.h"
#include "../../comm/ora_util.h"
#include "../ora_ttc_proto.h"
#include "../ora_mar_engine.h"
#include "ora_rowid_accessor.h"

/*******************************************************************************
*  FUNC     :  解析 rowid 类型数据
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  *p_st_metadata                       (meta信息)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_rowid_accessor_unmarshal_one_row(Conntrack *p_st_conn
                                        , L7session_ora *p_st_sess
                                        , L7_ora_packet *p_st_ora_packet
                                        , Sql_metadata_info *p_st_metadata)
{
    short s_tmp = 0;
    int i_tmp = 0;
    long long ll_tmp = 0LL;

    if (p_st_metadata->i_isuseless == FR_YES || p_st_metadata->i_isnullbydescribe == FR_YES)
        goto success;

    if (p_st_metadata->i_data_type == ORA_DTY_UROWID)
    {
        // XXX: 测试到oci的情况下null时为0x0000
        if (p_st_sess->i_use_special_field == FR_YES)
        {
            if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)
                goto error;
            if (i_tmp > 0)
            {
                if (ora_mar_skipCLR(p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
            }
        }
        else
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)
                goto error;
            if (ll_tmp > 0LL)
            {
                if (ora_mar_skipCLR(p_st_sess, p_st_ora_packet) != FR_SUCC)
                    goto error;
            }
        }
    }
    else
    {
        if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
            goto error;
        if (s_tmp > 0)
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)
                goto error;
            if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)
                goto error;
            if (p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_NO)
            {
                if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)
                    goto error;
            }
            else
            {
                if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC)
                    goto error;
            }
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC)
                goto error;
            if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)
                goto error;
            if (p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_NO)
            {
                if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC)
                    goto error;
            }
        }
    }

success:
    return FR_SUCC;
error:
    return FR_FAIL;
}
